#include "gt911_4.3.h"
#include "f1c100s_gpio.h"
#include "f1c100s_twi.h"
#include "f1c100s_intc.h"
#include "stdio.h"
#include "time0.h"
// 4.3寸 800x480 触摸屏幕资料 https://www.eya-display.com/jlt4305a  https://item.taobao.com/item.htm?abbucket=14&id=717028909992&ns=1&pisk=grkihgtkSfP6w8CQlHy6imlH9LOL5Gwb1qBYk-U2TyzCBSzv1qVmk2NqBRnt-ru-ooHtHxcCn0ijBhwvfRi_h-8JyLemfcwXgiuaRAbEYunFQNWweFnaHGTJyLpD_MyDSU392AMhLuqz3lPN36-3DozVuqPa8kzQco7a0O-nYyaFQNz40y7Uqu4VQqWaLwrbDZSa31JeLo4Uu-Pq_nX4rxkILFgMoLXnV2k3j54rxQ6VnSB8_zz48t8rdl47zczh3tz6671ZxcLGFDesB4q-WpWirclrubueKOVI_DD0NxOABcwUS7zqjN5aqR4gaAPO4Tw_gXD3BA8fNDn3772K9BTTMR0iNzNwOegmxP3qIW7MJrh-vAPnzeBnlScZSkyP4z5FaNaNhi7bts1b_kZ3y22wzNRcAM62xHfW15rQXUKHxsMz_kZIrHxhaUPaAlfF.&priceTId=214782d417284646809448800e3cf8&skuId=5020608117351&spm=a21n57.1.item.3.79ba523cTeN2RX&utparam=%7B%22aplus_abtest%22%3A%22ab22e0911774bfea286ff4daca074492%22%7D&xxc=taobaoSearch

/***GT911 pins
 *1.RST -> PA0
 *2.VDD
 *3.GND
 *4.INT -> PE12
 *5.SDA -> PD0
 *6.SCL -> PD12
 */
uint8_t cfg[GT9XX_CONFIG_LENGTH];
Twi_handle_def GT911_Handle = {.instance = TWI0, .clock = 200000, .device_addr = GT9XX_DEVICE_ID1, .reg_size = 16};

static void gt9xx_rst_pin_init();
static void gt9xx_int_pin_output();
static void gt9xx_int_pin_input();
static void gt9xx_i2c_init();
static void gt9xx_int_pin(uint8_t level);
static void gt9xx_rst_pin(uint8_t level);

void gt9xx_init_B();

#if config_USING_INT_PIN
void gt911_int_pin_irq_handle();
#endif

static void gt9xx_rst_pin_init()
{
    gpio_init(GPIOA, PIN0, GPIO_MODE_OUTPUT, GPIO_PULL_UP, GPIO_DRV_3); // PA0 rst pin
}

static void gt9xx_rst_pin(uint8_t level)
{
    if (level)
    {
        gpio_pin_set(GPIOA, 0);
    }
    else
    {
        gpio_pin_clear(GPIOA, 0);
    }
}

static void gt9xx_int_pin_output()
{

    gpio_init(GPIOE, PIN12, GPIO_MODE_OUTPUT, GPIO_PULL_UP, GPIO_DRV_3); // PE 12
}

static void gt9xx_int_pin_input()
{
    gpio_init(GPIOE, PIN12, GPIO_MODE_AF6, GPIO_PULL_NONE, GPIO_DRV_0); // PE12-EXTI.
// 中断配置
#if config_USING_INT_PIN
    eint_pin_init(GPIOE_INT, 12, EINT_TRG_FALLING);
    eint_pin_enable(GPIOE_INT, 12);
    intc_enable_irq(IRQ_GPIOE);
    intc_set_irq_handler(IRQ_GPIOE, gt911_int_pin_irq_handle);
#endif
}

static void gt9xx_int_pin(uint8_t level)
{
    {
        if (level)
        {
            gpio_pin_set(GPIOE, 12);
        }
        else
        {
            gpio_pin_clear(GPIOE, 12);
        }
    }
}
// 1ms单位
void gtx9xx_delay(uint16_t ms)
{
    delay(ms);
#if 0
    return;
    uint32_t max = ms * 1000 * 4;
    for (volatile uint32_t i = 0; i < max; i++)
    {
        for (volatile uint8_t j = 0; j < 48; j++)
        {
            asm("nop");
        }
    }
#endif
}

static void gt9xx_i2c_init()
{
    _TWI0_CLK_ENABLE();
    gpio_set(GPIOD, PIN0 | PIN12);
    gpio_init(GPIOD, PIN0 | PIN12, GPIO_MODE_AF3, GPIO_PULL_NONE, GPIO_DRV_3);
    Twi_Reset(&GT911_Handle);
    Twi_Init(&GT911_Handle);
    Twi_Enable(&GT911_Handle);
}

void gt9xx_init()
{
    /*0X14 时序, RST 0 ->INT 0 -> 0.1ms-> RST 1 -> 5ms-> INT input*/
    // IO INIT

    gt9xx_i2c_init();
    gt9xx_int_pin(0);
    gt9xx_rst_pin(0);
    gt9xx_int_pin_output();
    gt9xx_rst_pin_init();

    gtx9xx_delay(2);
    if (GT911_Handle.device_addr == GT9XX_DEVICE_ID2)
    {
        // INT 1
        gt9xx_int_pin(1);
    }
    gtx9xx_delay(6);

    // RST 1
    gt9xx_rst_pin(1);
    gtx9xx_delay(50);
    // int input
    gt9xx_int_pin_input(); // 切换到input模式 至少延迟50ms，否则读取坐标都是0，芯片可能锁死了

    printf("\r\ngt9xx init.\r\n");

    // soft reset
    uint8_t cmd_reset = 0x03;
    gt9xx_write_reg(GT9XX_COMMAND, &cmd_reset, 1);
    gtx9xx_delay(10);

    uint8_t id[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

    uint8_t temp[2] = {0, 0};

    gt9xx_read_reg(GT9XX_PRODUCT_ID, id, 11);
    gt9xx_read_reg(GT9XX_CONFIG, cfg, sizeof(cfg));
    printf("Line %d: gt9xx_id:%s verison:%c \r\n", __LINE__, id, cfg[0]);
    // printf("gt9xx_fw_ver:%d\r\n", id[4] | id[5] << 8);

    // 发送配置信息表 0x8040-0x8100
#if GT9XX_SEND_CFG
    cfg[0] = 0;
    gt9xx_write_reg(GT9XX_CONFIG, &cfg[0], 1);

    extern uint8_t s_GT911_Cfg[];
    s_GT911_Cfg[1] = (uint8_t)(GT9XX_X_MAX & 0Xff);
    s_GT911_Cfg[2] = (uint8_t)(GT9XX_X_MAX >> 8) & 0Xff;
    s_GT911_Cfg[3] = (uint8_t)(GT9XX_Y_MAX & 0Xff);
    s_GT911_Cfg[4] = (uint8_t)(GT9XX_Y_MAX >> 8) & 0Xff;
    s_GT911_Cfg[5] = 5;                           // 触摸点数
    s_GT911_Cfg[6] = 0x01 | (GT9XX_SWAP_XY << 3); // 下降沿触发 ，SWAPXY

    uint8_t tempck = 0;
    for (int i = 0; i < 184; i++)
    {
        tempck += s_GT911_Cfg[i];
    }
    tempck = ~tempck + 1;
    s_GT911_Cfg[184] = tempck; // 校验

    for (int i = 0; i < 186; i++)
    {
        gt9xx_write_reg(GT9XX_CONFIG + i, &s_GT911_Cfg[i], 1);
        gtx9xx_delay(2);
    }
#endif

    uint8_t swap_it = 0x01 | (GT9XX_SWAP_XY << 3); // 下降沿触发 ，SWAPXY
    gt9xx_write_reg(GT9XX_CONFIG_IT_MODE, &swap_it, 1);
    gt9xx_read_reg(GT9XX_CONFIG_IT_MODE, temp, 1);
    printf("Line %d: swap XY:%x\r\n", __LINE__, (temp[0] && 0x08) >> 3);

    uint8_t xymax[] = {(uint8_t)(GT9XX_X_MAX & 0Xff), ((uint8_t)(GT9XX_X_MAX >> 8) & 0Xff), (uint8_t)(GT9XX_Y_MAX & 0Xff), ((uint8_t)(GT9XX_Y_MAX >> 8) & 0Xff)};
    gt9xx_write_reg(GT9XX_CONFIG_XY_MAX, xymax, sizeof(xymax));

    gt9xx_read_reg(GT9XX_CONFIG, cfg, sizeof(cfg));
    uint8_t checksum[2] = {0, 1};
    for (int i = 0; i < GT9XX_CONFIG_LENGTH; i++)
        checksum[0] += cfg[i];
    checksum[0] = ~checksum[0] + 1;

    gt9xx_read_reg(GT9XX_CONFIG_CHECK, temp, 1);

    if (temp[0] == checksum[0])
    {
        printf("Line %d: gt9xx config checksum OK:0x%x\r\n", __LINE__, checksum[0]);
    }
    else
    {
        gt9xx_write_reg(GT9XX_CONFIG_CHECK, checksum, 2);
        printf("Line %d: gt9xx config checksum err,write config now. 0x%x\r\n", __LINE__, checksum[0]);
    }

    gt9xx_read_reg(GT9XX_CONFIG, cfg, 10);

#if GT9XX_DISP_MODE
    printf("\r\nLine %d:ver:%c , xmax:%d ,ymax:%d  tpnums:%d\r\n", __LINE__, cfg[0], cfg[3] | cfg[4] << 8, cfg[1] | cfg[2] << 8, cfg[5]);
#else
    printf("\r\nLine %d:ver:%c , xmax:%d ymax:%d ,tpnums:%d\r\n", __LINE__, cfg[0], cfg[1] | cfg[2] << 8, cfg[3] | cfg[4] << 8, cfg[5]);
#endif
    // soft reset
    gt9xx_write_reg(GT9XX_COMMAND, &cmd_reset, 1);
    gtx9xx_delay(10);
}

uint8_t gt9xx_read_tp(gt9xx_tpdef *tp)
{
    gt9xx_tp_point_reg_def tp_reg[5];
    uint8_t status[2] = {0};
    gt9xx_read_reg(GT9XX_TP_STATE, status, 2);
    if (status[0])
    {
        uint8_t clear_flag = 0;
        gt9xx_write_reg(GT9XX_TP_STATE, &clear_flag, 1);
    }
    tp->nums = status[0] & 0x0f;
    if (tp->nums)
    {
        for (uint8_t i = 0; i < tp->nums; i++)
        {
            gt9xx_read_reg(GT9XX_TP1 + i * 8, (uint8_t *)&tp_reg[i], 8);

#if GT9XX_DISP_MODE
            tp->point[i].y = (uint16_t)(tp_reg[i].xl | (uint16_t)(tp_reg[i].xh << 8));
            tp->point[i].x = (uint16_t)(tp_reg[i].yl | (uint16_t)(tp_reg[i].yh << 8));
#else
            tp->point[i].x = (uint16_t)(tp_reg[i].xl | (uint16_t)(tp_reg[i].xh << 8));
            tp->point[i].y = (uint16_t)(tp_reg[i].yl | (uint16_t)(tp_reg[i].yh << 8));
#endif
        }

        printf("tp:%d\r\n", tp->nums);
        printf("tp_status: %d  %d\r\n", status[0], status[1]);
    }

    return tp->nums;
}

void gt9xx_read_reg(uint16_t reg_addr, uint8_t *read, uint16_t length)
{
    Twi_read_reg(&GT911_Handle, reg_addr, read, length);
}

void gt9xx_write_reg(uint16_t reg_addr, uint8_t *read, uint16_t length)
{
    Twi_write_reg(&GT911_Handle, reg_addr, read, length);
}

#if config_USING_INT_PIN
void gt911_int_pin_irq_handle()
{
    uint8_t eint_status = eint_pin_get_status(GPIOE_INT, 12);
    if (eint_status)
    {
        printf("PE12 EXIT. %d\r\n", eint_status);
    }
    eint_pin_clear_status(GPIOE_INT, 12);
}
#endif

void gt9xx_init_B()
{
    gt9xx_int_pin_output();
    gt9xx_rst_pin_init();

    gt9xx_int_pin(0);
    gt9xx_rst_pin(0);
    gtx9xx_delay(2);
    gt9xx_rst_pin(1);
    gt9xx_i2c_init();
    gtx9xx_delay(10);

    printf("\r\ngt9xx init.\r\n");
    // uint8_t cfg1[] = {00, 0x20, 0x03, 0xe0, 0x1, 0x05, 0x00};
    // gt9xx_write_reg(GT9XX_CONFIG, cfg1, 7);

    uint8_t id[11] = {0};
    gt9xx_read_reg(GT9XX_PRODUCT_ID, id, 11);

    printf("\r\ngt9xx_id:%s \r\n", id);
    printf("gt9xx_fw_ver:%d\r\n", id[4] | id[5] << 8);

    printf("***********************\r\n");

    gt9xx_read_reg(0x8047, cfg, 11);
    for (int i = 0; i < 11; i++)
    {
        printf("0x %02x \r\n", cfg[i]);
    }
}
